package yannan.voiplock4ble;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.umeng.analytics.MobclickAgent;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.util.Arrays;

import butterknife.Bind;
import butterknife.OnClick;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import yannan.voiplock4ble.base.Content;
import yannan.voiplock4ble.base.LoggedBaseActivity;
import yannan.voiplock4ble.base.MyApplication;
import yannan.voiplock4ble.download.ProgressResponseListener;
import yannan.voiplock4ble.eventbus.BaseEventMsg;
import yannan.voiplock4ble.eventbus.EventObject;
import yannan.voiplock4ble.eventbus.RemoteUpgradeACKMsg;
import yannan.voiplock4ble.eventbus.UpgradeACKMsg;
import yannan.voiplock4ble.net.NetUtils;
import yannan.voiplock4ble.net.base.NetworkService;
import yannan.voiplock4ble.service.ble.BleService;
import yannan.voiplock4ble.service.ble.BleUtils;
import yannan.voiplock4ble.utils.AnimUtils;
import yannan.voiplock4ble.utils.FileUtils;
import yannan.voiplock4ble.utils.PopShowUtils;
import yannan.voiplock4ble.utils.StringEncrypt;
import yannan.voiplock4ble.utils.ToastUtils;

/**
 * 门锁升级页面
 */
@Content(R.layout.activity_lock_update)
public class LockUpdateActivity extends LoggedBaseActivity implements View.OnClickListener {

    @Bind(R.id.pro_downprogress)
    ProgressBar proDownprogress;
    @Bind(R.id.tv_downprogress)
    TextView tvDownprogress;
    @Bind(R.id.lin_lock_update_download)
    LinearLayout linLockUpdateDownload;
    @Bind(R.id.tv_update_finish)
    TextView tvUpdateFinish;
    @Bind(R.id.btn_lock_setting)
    TextView btnLockSetting;
    @Bind(R.id.btn_lock_update)
    TextView btn_lock_update;
    @Bind(R.id.rel_update_package_finish)
    RelativeLayout relUpdatePackageFinish;
    @Bind(R.id.img_download)
    ImageView imgDownload;
    @Bind(R.id.tv_download_tips)
    TextView tvDownloadTips;
    private NetworkService networkService;
    private File updateFile;
    private byte[] fileBytes;
    private int pktSize;// 每包大小
    private int pktTotal; //总包数
    private int lastSn; //最后一个发送的包的编号
    private int pkgType;


    @Override
    public void initData() {
//        MyApplication.getInterface().activityMap.put(this.getLocalClassName(), this);
        setTitleTheme(TitleTheme.TOOLBAR_THEME_COMMON, "门锁设置");
        linLockUpdateDownload.setVisibility(View.VISIBLE);
        relUpdatePackageFinish.setVisibility(View.GONE);
        proDownprogress.setProgress(0);
        btnLockSetting.setEnabled(false);
        pkgType = getIntent().getIntExtra("lockFirPkgType", 0);
        String url = getIntent().getStringExtra("lockFirUrl");
        //根据传递过来的地址 和标志下载升级包
        downUpgradePack(url);
    }


    private void downUpgradePack(final String url) {

        // TODO: 2017/2/14 检查本地是否已经有了当前文件
        updateFile = FileUtils.readFile(Environment.getExternalStorageDirectory() + "/vipLock/" +
                StringEncrypt.EncryptByMD5(url) + ".octet-stream");
        if (updateFile != null) {
            proDownprogress.setProgress(100);
            tvDownprogress.setText("已下载" + 100 + "%");
            tvDownloadTips.setText("升级包下载完毕，请点击开始升级");
            btn_lock_update.setEnabled(true);
            return;
        }

        NetUtils.getNetworkService(new ProgressResponseListener() {
            @Override
            public void onResponseProgress(long bytesRead, long contentLength, boolean done) {
                Log.e("LockUpdateActivity", "contentLength:" + contentLength);
                Log.e("LockUpdateActivity", "bytesRead:" + bytesRead);
                Message message = new Message();
                message.what = down_pro;
                message.obj = bytesRead * 100 / contentLength;
                handler.sendMessage(message);
            }
        })
                .downLoad(url)
                .enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        updateFile = FileUtils.saveFile(response.body().byteStream(),
                                Environment.getExternalStorageDirectory() + "/vipLock",
                                StringEncrypt.EncryptByMD5(url) + "." + response.body().contentType().subtype());
                        if (updateFile != null) {
                            //如果不为空 开始升级
                            btn_lock_update.setEnabled(true);
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {
                        Log.e("LockUpdateActivity", "onFailure");
                    }
                });
    }

    @Override
    protected void onResume() {
        super.onResume();
        MobclickAgent.onPageStart("LockUpdateActivity");
        MobclickAgent.onResume(this);
    }

    @Override
    protected void onPause() {
        super.onPause();
        MobclickAgent.onPageEnd("LockUpdateActivity");
        MobclickAgent.onPause(this);
    }

    /**
     * 下载完成
     */
    private void downFinish2Sync() {
        AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.0f);
        alphaAnimation.setDuration(600);
        alphaAnimation.setFillAfter(true);
        linLockUpdateDownload.startAnimation(alphaAnimation);
        alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                linLockUpdateDownload.setVisibility(View.GONE);
                proDownprogress.setProgress(0);
                tvDownprogress.setText("已同步0%");
                imgDownload.setImageResource(R.drawable.ic_synchronize);
                tvDownloadTips.setText("正在将升级包同步到门锁，请保持将手机保持在门锁两米范围内！");
                AlphaAnimation alphaAnimation1 = new AlphaAnimation(0.0f, 1.0f);
                alphaAnimation1.setDuration(600);
                alphaAnimation1.setFillAfter(true);
                linLockUpdateDownload.startAnimation(alphaAnimation1);
                linLockUpdateDownload.setVisibility(View.VISIBLE);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }
        });
    }

    /**
     * 同步完成
     */
    private void SyncFinish() {
        AnimUtils.alphaAnimation(linLockUpdateDownload, relUpdatePackageFinish);
        btnLockSetting.setEnabled(true);
    }

    /**
     * 传数据到蓝牙
     */
    private void post2Ble() {
        ToastUtils.showToast(LockUpdateActivity.this, "传数据到蓝牙");
    }

    @OnClick({R.id.btn_lock_setting})
    public void Onclick(View view) {
        post2Ble();
    }

    final static int down_pro = 10020;
    final static int up_pro = 10021;
    int i = 0;
    final int START_UPDATE_LOCK = 10010;
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case down_pro:
                    long pro = (long) msg.obj;
                    proDownprogress.setProgress((int) pro);
                    tvDownprogress.setText("已下载" + (int) pro + "%");
                    break;
                case up_pro:
                    long proUp = (long) msg.obj;
                    proDownprogress.setProgress((int) proUp);
                    tvDownprogress.setText("已同步" + (int) proUp + "%");
                    break;
                case START_UPDATE_LOCK: //重发三次
                    if (msg.getData().getInt("i") < 3) {
                        BleService.getBleService().sendOrder(msg.getData().getByteArray("order"));
                        sendMessageDel(msg.getData().getByteArray("order"), START_UPDATE_LOCK, msg.getData().getInt("i") + 1);
                    } else {
                        PopShowUtils.showCommonDialog(mContext, "对不起，发送升级包失败，请重新连接门锁，尝试重新升级！", null, "确定", false,
                                new PopShowUtils.IDialogCommonListener() {
                                    @Override
                                    public void onClick(int direction) {
                                        finish();
                                    }
                                });
                    }
                    break;
            }
        }
    };

    @Override
    public void onBackPressed() {
        PopShowUtils.showCommonDialog(mContext, "是否退出门锁升级？", "取消", "确定", false, new PopShowUtils.IDialogCommonListener() {
            @Override
            public void onClick(int direction) {
                if (direction == PopShowUtils.COMMON_DIALOG_RIGHT)
                    finish();
            }
        });
    }

    @OnClick({R.id.btn_lock_update})
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_lock_update:  //开始发送升级命令  同步升级包
                btn_lock_update.setKeepScreenOn(true);
                downFinish2Sync();
                fileBytes = FileUtils.readFile(updateFile);
                if (fileBytes == null) {
                    //读取文件错误，给出提示
                    break;
                }
                if (MyApplication.getInterface().mConnectLock == null || MyApplication.getInterface().mConnectLock.contentToken == 0) {
                    ToastUtils.showToast(mContext, "门锁未连接，请先链接门锁");
                    break;
                }
                byte[] order = BleUtils.update(fileBytes, new byte[1], MyApplication.getInterface().mConnectLock.contentToken,
                        pkgType, fileBytes.length);
                BleService.getBleService().sendOrder(order);
                btn_lock_update.setEnabled(false);
                sendMessageDel(order, START_UPDATE_LOCK, 1);
                break;
        }
    }

    /**
     * 发送延迟消息
     *
     * @param order
     */
    private void sendMessageDel(byte[] order, int what, int i) {
        Message message = new Message();
        message.what = what;
        Bundle bundle = new Bundle();
        bundle.putByteArray("order", order);
        bundle.putInt("i", i);
        message.setData(bundle);
        handler.sendMessageDelayed(message, 3000);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(BaseEventMsg msg) {
        if (msg instanceof RemoteUpgradeACKMsg) {
            RemoteUpgradeACKMsg upgradeACKMsg = (RemoteUpgradeACKMsg) msg;
            handler.removeMessages(START_UPDATE_LOCK);
            if (upgradeACKMsg.upgradeACK.reason) { //可以升级

                pktSize = upgradeACKMsg.upgradeACK.pkt_size;
                pktTotal = fileBytes.length % pktSize == 0 ? fileBytes.length / pktSize : fileBytes.length / pktSize + 1;
                int startSn = upgradeACKMsg.upgradeACK.start_sn;
                //开始发送
                sendPackage(startSn);
            } else {
                // TODO: 2017/2/10 不能升级 应该给出提示
                PopShowUtils.showCommonDialog(mContext, "对不起，门锁暂不支持升级到此版本！", null, "确定", false, new PopShowUtils.IDialogCommonListener() {
                    @Override
                    public void onClick(int direction) {
                        finish();
                    }
                });
            }
        } else if (msg instanceof UpgradeACKMsg) {
            handler.removeMessages(START_UPDATE_LOCK);
            UpgradeACKMsg upgradeACKMsg = (UpgradeACKMsg) msg;
            if (upgradeACKMsg.upgradeACK.reason) { //上一个包接收成功 继续发送下一个
                sendPackage(upgradeACKMsg.upgradeACK.pkt_sn + 1);
            } else {
                //上一个包发送失败，重新发送
                sendPackage(lastSn);
            }
        } else if (msg instanceof EventObject) {
            EventObject object = (EventObject) msg;
            if (object.eventIntTag == 0) {
                PopShowUtils.showCommonDialog(mContext, "门锁正在升级中，请等待门锁重新启动以完成升级！",
                        null, "确定", false, new PopShowUtils.IDialogCommonListener() {
                            @Override
                            public void onClick(int direction) {
                                finish();
                            }
                        });
            }
        }
    }

    /**
     * 发生升级包
     *
     * @param pktSn
     */
    private void sendPackage(int pktSn) {

        if (MyApplication.getInterface().mConnectLock == null || MyApplication.getInterface().mConnectLock.contentToken == 0) {
            ToastUtils.showToast(mContext, "蓝牙已断开，请重新连接");
            return;
        }
        Message message = new Message();
        message.what = up_pro;
        if (pktSn + 1 < pktTotal) {
            byte[] pkt = Arrays.copyOfRange(fileBytes, pktSn * pktSize, (pktSn + 1) * pktSize);
            byte[] order = BleUtils.sendUpdatePkt(
                    pkt, pktSn, pkt.length, MyApplication.getInterface().mConnectLock.contentToken);
            BleService.getBleService().sendOrder(order);
            lastSn = pktSn;
            message.obj = (long) pktSn * 100 / (long) pktTotal;
            handler.sendMessage(message);
            sendMessageDel(order, START_UPDATE_LOCK, 1);
        } else if (pktSn + 1 == pktTotal) {
            byte[] pkt = Arrays.copyOfRange(fileBytes, pktSn * pktSize, fileBytes.length);
            byte[] order = BleUtils.sendUpdatePkt(
                    pkt, pktSn, pkt.length, MyApplication.getInterface().mConnectLock.contentToken);
            BleService.getBleService().sendOrder(order);
            sendMessageDel(order, START_UPDATE_LOCK, 1);
            lastSn = pktSn;
            message.obj = (long) pktSn * 100 / (long) pktTotal;
            handler.sendMessage(message);
        } else if (pktSn == pktTotal) { //所有升级包发送完毕 发送升级命令
            message.obj = 100l;
            handler.sendMessage(message);
            btn_lock_update.setKeepScreenOn(false);
            BleService.getBleService().sendOrder(BleUtils.startUpdate(
                    MyApplication.getInterface().mConnectLock.contentToken
            ));
            PopShowUtils.showCommonDialog(mContext, "升级包同步完成，请在门锁上确认升级！", null, "确定", false, new PopShowUtils.IDialogCommonListener() {
                @Override
                public void onClick(int direction) {
                    finish();
                }
            });
        }
    }
}
